#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>

int pid_neto;

//recebe o tempo e o nome do filho e vai lançar filhos do filho para explorar concorrência
void codigofilho(int tempo, char *prog, int i) {

	alarm(tempo);

	pid_neto = fork();

	if (pid_neto == 0) {
		//passa o nome do programa

		char iStr[2];
		sprintf(iStr, "%d", i);



		execl(prog, prog,iStr , NULL);
		perror("execlp");
		exit(EXIT_FAILURE);
	} else {
	wait(NULL);//espera que o neto termine, mas neste caso o filho deste aqui
	}

}

void killer(int x) {

	// Enviar sinal ao filho que está actualmente a correr, para suspender execução.
	kill(pid_neto, SIGKILL);
}

int main(int argc, char * argv[]) {

	if (argc < 4 ) {
		fprintf(stderr,"Usage: %s <N> <S> [progs]\n",argv[0]);
		exit(EXIT_FAILURE);
	}

	int numeroProgramas = argc - 3 ;
	int maxN = atoi (argv[1]);
	int maxS = atoi (argv[2]);
	// int i = 3;//argumentos que são passados
	int n = 0;//quantos gajos já correm
	int * filhos;
	int terminados = 0;

	//percorrer os programas passados (isto funca?) vi esta ideia na net
	filhos = (int *) malloc(sizeof(int) * (numeroProgramas));
	// armadilhar
	signal(SIGALRM, killer);

	//garatir que tem mais de 3 argumentos
	int i = 0 ;
	for (i = 0; i < numeroProgramas; i++) {
		//verificar se ainda temos menos de N programas a correr
		if (n < maxN) {
			filhos[i] = fork();
			if (filhos[i] == 0) {
				//vai criar o filho que corre o programa durante o tempo dado em N(argv[2]
				codigofilho(maxS, argv[i+3],i);
				exit(EXIT_SUCCESS);
			} else {
				n++;//incrementa numero de programas a correr
			}

		} else {
			wait(NULL);
			//espera que o filho termine
			n--;//terminou, desincrementa o numero de progs a correr
			terminados++;//mais um terminadinho!
			i--;// porque n verdade, argv[i+3] n foi executado
		}
	} // end for

	while (terminados < numeroProgramas) {
		wait(NULL);
		//espera que o filho termine
		terminados++;
	}

	return 0 ;
}
